package com.xx.ems.controller;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.xx.ems.system.BaseController;

/**
 * @author xxx
 * @date 2014-3-4
 * @version 1.0
 * 描述: 数据库操作 (备份与还原)
 */
@Controller
@RequestMapping(value="database",method=RequestMethod.POST)
public class DatabaseController extends BaseController {
	/**
	 * 数据库连接信息
	 */
	private final static String username = "root";
	private final static String password = "root";
	private final static String database = "emsdb";
	private final static String host = "localhost";
	/**
	 * 备份数据库文件存放的文件夹
	 */
	private final static String path = "/backup";
	
	/**
	 * 描述: 备份数据库 
	 * @param request
	 * @param response
	 * @throws Exception
	 * @date 2014-3-4
	 */
	@RequestMapping(value="/backupDatabase")
	public void backupDatabase(HttpServletRequest request, HttpServletResponse response) throws Exception{
		JSONObject json = new JSONObject();
		response.setContentType("application/json");
		
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		FileOutputStream fos = null;
		OutputStreamWriter writer = null;
		try{
			Runtime rt = Runtime.getRuntime();
			/**
			 * mysql的安装目录需要根据实际情况进行修改
			 */
			String str = "D://Program Files//MySQL Server 5.5//bin//mysqldump -h " + host + " -u" + username + " -p" + password + " " + database;
			/**
			 * 执行mysql导出数据库操作
			 */
			Process child = rt.exec(str);
			/**
			 * 把进程执行中的控制台输出信息作为输入流
			 */
			is = child.getInputStream();
			/**
			 * 设置输出流编码为utf-8。这里必须是utf-8，否则从流中读入的是乱码
			 */
			isr = new InputStreamReader(is, "utf-8");

			/**
			 * 将控制台输出信息组合成字符串
			 */
			br = new BufferedReader(isr);
			String inStr = null;
			StringBuffer sb = new StringBuffer("");
			while ((inStr = br.readLine()) != null) {
				sb.append(inStr + "\r\n");
			}
			String outStr = sb.toString();
			
			/**
			 * 获取备份得到的数据库文件的存放的路径
			 */
			String targetDirectory = request.getSession().getServletContext().getRealPath(path);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			String filePath = targetDirectory + "/db备份于" + sdf.format(new Date()) + ".sql";
			/**
			 * 将得到控制台输出信息字符串写入到指定文件中
			 */
			fos = new FileOutputStream(filePath);
			writer = new OutputStreamWriter(fos, "utf-8");
			writer.write(outStr);
			writer.flush();
			
			json.put("result", "suc");
		}catch (Exception e) {
			e.printStackTrace();
			json.put("result", "fail");
		}finally {
			/**
			 * 关闭相关的流
			 */
			is.close();
			isr.close();
			br.close();
			fos.close();
			writer.close();
			response.getWriter().println(json.toString());
		}
	}
	
	/**
	 * 描述: 还原数据库 
	 * @param fileName
	 * @param request
	 * @param response
	 * @throws IOException 
	 * @throws JSONException 
	 * @date 2014-3-5
	 */
	@RequestMapping(value="/restoreDatabase")
	public void restoreDatabase(String fileName,HttpServletRequest request, HttpServletResponse response) throws IOException, JSONException {
		JSONObject json = new JSONObject();
		response.setContentType("application/json");
		
		OutputStream out = null;
		BufferedReader br = null;
		OutputStreamWriter writer = null;
		try{
			Runtime rt = Runtime.getRuntime();
            String str = "D://Program Files//MySQL Server 5.5//bin//mysql.exe -u" + username + " -p" + password + " " + database;
            Process child = rt.exec(str);
            /**
             * 获取相对路径
             */
            String targetDirectory = request.getSession().getServletContext().getRealPath(path);
            /**
             * 将控制台的输入信息作为输出流 
             */
            out = child.getOutputStream();
            String inStr;
            StringBuffer sb = new StringBuffer("");      
            br = new BufferedReader(new InputStreamReader(new FileInputStream(targetDirectory+"//"+fileName), "utf8"));      
            while ((inStr = br.readLine()) != null) {
                sb.append(inStr + "\r\n");
            }
            String outStr = sb.toString();
     
            writer = new OutputStreamWriter(out, "utf8");
            writer.write(outStr);
            writer.flush();
            
            json.put("result", "suc");
        }catch (Exception e) {
            e.printStackTrace();
            json.put("result", "fail");
        }finally {
        	//关闭流
            out.close();
            br.close();
            writer.close();
            response.getWriter().println(json.toString());
        }
	}
	
	/**
	 * 描述: 下载数据库备份文件
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 * @date 2014-3-5
	 * 
	 * 前台通过为元素绑定以下事件来进行文件下载
	 * function download() {
	 * 		var form = $("<form>");
	 * 		form.attr("style","display:none");
	 * 		form.attr("method","post");
	 * 		form.attr("action","/ems/database/downloadDatabase");
	 * 		var input1 = $("<input>");
	 * 		input1.attr("type","hidden");
	 * 		input1.attr("name","fileName");
	 * 		input1.attr("value","db备份于20140304231647.sql");
	 * 		$("body").append(form);  //将表单放置在web中
	 * 		form.append(input1);
	 * 		form.submit();  //表单提交 
	 * }
	 */
	@RequestMapping("/downloadDatabase")  
	public void downloadDatabase(HttpServletRequest request, HttpServletResponse response) throws IOException {
		/**
		 * 设置请求的编码格式,解决乱码的问题
		 */
		request.setCharacterEncoding("UTF-8");
		String fileName = request.getParameter("fileName");
		String targetDirectory = request.getSession().getServletContext().getRealPath(path);
		File file = new File(targetDirectory+"//"+fileName);
		/**
		 * 清空response,并设置相应的信息
		 */
        response.reset();
        response.setContentType("application/x-download");
        response.setContentLength((int) file.length());
        /**
         * 判断是否为IE浏览器
         */
        String userAgent = request.getHeader("User-Agent");
        boolean isIE = (userAgent != null) && (userAgent.toLowerCase().indexOf("msie") != -1);
        if (isIE) {
        	fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        }else {
        	fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        }
        BufferedInputStream is = null;
        OutputStream os = null;
        try{
        	is = new BufferedInputStream(new FileInputStream(file));
            os = response.getOutputStream();
            IOUtils.copy(is, os);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(is);
        }
	}
	
	/**
	 * 描述: 获取备份文件列表 
	 * @param request
	 * @param response
	 * @throws JSONException 
	 * @throws IOException 
	 * @date 2014-3-6
	 */
	@RequestMapping(value="/getBackupFileList")
	public void getBackupFileList(HttpServletRequest request, HttpServletResponse response) throws JSONException, IOException {
		JSONObject json = new JSONObject();
		response.setContentType("application/json");
		try{
			List<String> backupFileList = new ArrayList<String>();
			String targetDirectory = request.getSession().getServletContext().getRealPath(path);
			File file = new File(targetDirectory);
			File[] files = file.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (files[i].isDirectory() != true) {
						backupFileList.add(files[i].getName());
					}
				}
			}
			json.put("result", backupFileList);
		}catch (Exception e) {
			e.printStackTrace();
			json.put("result", "fail");
		}finally {
			response.setCharacterEncoding("UTF-8");
			response.getWriter().println(json.toString());
		}
	}
}